﻿
#region Copyright & License
// --------------------------
// Copyright 2008 Daniel Gray
// --------------------------
// This file is part of Kale.
//
// Kale is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Kale is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Kale.  If not, see <http://www.gnu.org/licenses/>.
#endregion
#region File details
// --------------------------------------------------------
// Filename          : RootNodeProvider.cs
// Author            : Daniel Gray
// Created           : 15/04/2008
// --------------------------------------------------------
#endregion
            
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kale.Core.Configuration;

namespace Kale.Core
{
   public class RootNodeProvider : INodeProvider
   {
      private IImageNode _root;
      private Dictionary<NodeSource, INodeProvider> _sourceProviders = new Dictionary<NodeSource, INodeProvider>();

      public RootNodeProvider()
      {
         _root = new ImageNode(new NodeId(NodeSource.Root, string.Empty, string.Empty), NodeType.Folder, string.Empty, "Image Sources", this);
      }

      public void AddSourceNodeProvider(INodeProvider provider)
      {
         lock (_sourceProviders)
         {
            if (!_sourceProviders.ContainsKey(provider.SupportedNodeSourceType))
            {
               _sourceProviders.Add(provider.SupportedNodeSourceType, provider);
            }
         }
      }

      #region INodeProvider Members

      public void ClearCaches()
      {
         lock (_sourceProviders)
         {
            foreach (INodeProvider provider in _sourceProviders.Values) provider.ClearCaches();
         }
      }

      public IImageNode LoadNode(NodeId id)
      {
         if (id == _root.NodeId)
         {
            return _root;
         }
         else if (_sourceProviders.ContainsKey(id.Source))
         {
            return _sourceProviders[id.Source].LoadNode(id);
         }
         else
         {
            return null;
         }
      }

      public IImageNode[] LoadChildren(NodeId id)
      {
         if (id == _root.NodeId)
         {
            List<IImageNode> allChildNodes = new List<IImageNode>();

            foreach (INodeProvider provider in _sourceProviders.Values)
            {
               NodeId childId = new NodeId(provider.SupportedNodeSourceType, string.Empty, string.Empty);

               allChildNodes.Add(provider.LoadNode(childId));
            }

            return allChildNodes.ToArray();
         }
         else if (_sourceProviders.ContainsKey(id.Source))
         {
            return _sourceProviders[id.Source].LoadChildren(id);
         }
         else
         {
            return new IImageNode[0];
         }
      }

      public IImageNode LoadParent(NodeId id)
      {
         if (id == _root.NodeId) return null;
         if ((id.Source == NodeSource.Disk || id.Source == NodeSource.Album) && string.IsNullOrEmpty(id.Store))
         {
            return _root;
         }

         if (_sourceProviders.ContainsKey(id.Source))
         {
            return _sourceProviders[id.Source].LoadParent(id);
         }
         else
         {
            return null;
         }
      }

      public NodeSource SupportedNodeSourceType
      {
         get { return NodeSource.Root; }
      }

      public NodeSource? SupportedParentNodeSourceType
      {
         get { return null; }
      }

      public string Name
      {
         get { return "Root"; }
      }

      #endregion

      private static RootNodeProvider _instance;

      public static INodeProvider Instance
      {
         get { return _instance; }
      }

      static RootNodeProvider()
      {
         _instance = new RootNodeProvider();

         _instance.AddSourceNodeProvider(SourceNodeProvider.CreateDiskSourceNodeProviderFromConfig(_instance, KaleConfigurationSection.Default.DiskStores));

      }
   }
}
